package com.dotandmedia.action;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.dotmedia.dboperations.RoleDatabaseOperations;
import com.dotmedia.dboperations.SystemDatabaseOperations;
import com.dotmedia.dboperations.UITranslationsDatabaseOperations;
import com.dotmedia.dboperations.UserDatabaseOperations;
import com.dotmedia.entities.Role;
import com.dotmedia.entities.SystemEntity;
import com.dotmedia.entities.UITranslations;
import com.dotmedia.entities.User;
import com.opensymphony.xwork2.ActionSupport;

public class AddNewUserAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {

	private static Logger logger = Logger.getLogger("AddNewUserAction");
	private static String USER_ALREADY_EXIST = "user.already.exist";

	private String userExtId;
	private String userEmail;
	private String userPassword;
	private String userName;
	private String surname;
	private String userRole;
	private String expireOnDate;
	private String langCode;

	protected Map session;
	protected HttpServletRequest request;
	protected HttpServletResponse response;

	@Override
	public void setServletResponse(HttpServletResponse resp) {
		this.response = resp;
	}

	@Override
	public void setServletRequest(HttpServletRequest req) {
		this.request = req;
	}

	@Override
	public void setSession(Map session) {
		this.session = session;
	}

	public String getUserExtId() {
		return userExtId;
	}

	public void setUserExtId(String userExtId) {
		this.userExtId = userExtId;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getSurname() {
		return surname;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}

	public String getUserRole() {
		return userRole;
	}

	public void setUserRole(String userRole) {
		this.userRole = userRole;
	}

	public String getExpireOnDate() {
		return expireOnDate;
	}

	public void setExpireOnDate(String expireOnDate) {
		this.expireOnDate = expireOnDate;
	}

	public String getLangCode() {
		return langCode;
	}

	public void setLangCode(String langCode) {
		this.langCode = langCode;
	}

	/**
	 * This method is the action class which adds new user. Check whether a user with the userExtId already exist or not Get a Role object of the role
	 * passed to this action class Make a user object and persist it in the database
	 * 
	 * @return
	 */
	public String addNewUser() {
		logger.info("IN AddNewUserAction");
		logger.info("User Ext id received: " + userExtId);
		logger.info("User email received: " + userEmail);
		logger.info("User name received: " + userName);
		logger.info("Surname received: " + surname);
		logger.info("User role received: " + userRole);
		logger.info("Expire on date received: " + expireOnDate);
		DateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
		Date expiryDate = null;
		try {
			expiryDate = simpleDateFormat.parse(expireOnDate);
		} catch (ParseException e) {
			logger.error("Cannot parse date in AddNewUserAction");
			logger.info("OUT AddNewUserAction");
			return ERROR;
		}
		UserDatabaseOperations userDatabaseOperations = new UserDatabaseOperations();
		List<User> usersWithExtId = userDatabaseOperations.getUserEntitiesWithExtId(userExtId);
		boolean userAlreadyExist = false;
		for (int usersWithExtIdIndex = 0; usersWithExtIdIndex < usersWithExtId.size(); usersWithExtIdIndex++) {
			User currentUser = usersWithExtId.get(usersWithExtIdIndex);
			if (currentUser.getUserExtId().equals(userExtId)) {
				logger.error("A user with the userExtId already exist in the database. Cannot add new user");
				userAlreadyExist = true;
				break;
			}
		}
		if (userAlreadyExist) {
			logger.error("A user with the userExtId already exist");
			logger.info("OUT AddNewUserAction");
			return USER_ALREADY_EXIST;
		} else {
			// user does not exist now
			RoleDatabaseOperations roleDatabaseOperations = new RoleDatabaseOperations();
			List<Role> rolesWithRoleString = roleDatabaseOperations.getRoleEntitiesWithExtId(userRole);
			boolean roleFound = false;
			Role retrivedRole = null;
			for (int rolesWithRoleStringIndex = 0; rolesWithRoleStringIndex < rolesWithRoleString.size(); rolesWithRoleStringIndex++) {
				Role currentRole = rolesWithRoleString.get(rolesWithRoleStringIndex);
				if (currentRole.getRoleExtId().equals(userRole)) {
					logger.info("Found the Role object with role ext id = " + userRole);
					retrivedRole = currentRole;
					roleFound = true;
					break;
				}
			}
			if (roleFound) {
				logger.info("We have found the Role object with the role ext id = " + userRole);
				// get the UITranslations object
				UITranslationsDatabaseOperations uiTranslationsDatabaseOperations = new UITranslationsDatabaseOperations();
				List<UITranslations> uiTranslationsList = uiTranslationsDatabaseOperations.getUITranslationsEntitiesWithLangCode(langCode);
				UITranslations retrievedUIObj = null;
				boolean uiObjFound = false;
				for (int uiTranslationsListIndex = 0; uiTranslationsListIndex < uiTranslationsList.size(); uiTranslationsListIndex++) {
					UITranslations currentUIObj = uiTranslationsList.get(uiTranslationsListIndex);
					if (currentUIObj.getLangCode().equals(langCode)) {
						uiObjFound = true;
						retrievedUIObj = currentUIObj;
						logger.info("UITranslations object found");
						break;
					}
				}
				// get the systems object as well
				boolean systemEntityFound = false;
				SystemDatabaseOperations systemDatabaseOperations = new SystemDatabaseOperations();
				List<SystemEntity> systemEntitiesList = systemDatabaseOperations.getSystemEntitiesWithLangCode(langCode);
				SystemEntity retrievedSystemEntityObj = null;
				for (int retrievedSystemEntityIndex = 0; retrievedSystemEntityIndex < systemEntitiesList.size(); retrievedSystemEntityIndex++) {
					SystemEntity currentSystemEntity = systemEntitiesList.get(retrievedSystemEntityIndex);
					if (currentSystemEntity.getDefaultLangCode().getLangCode().equals(langCode)) {
						retrievedSystemEntityObj = currentSystemEntity;
						systemEntityFound = true;
						logger.info("System Entity found");
						break;
					}
				}
				if (uiObjFound && systemEntityFound) {
					User userToBeAdded = new User(userExtId, userName, surname, userEmail, userPassword, retrivedRole, expiryDate, retrievedUIObj,
							retrievedSystemEntityObj);
					userDatabaseOperations.persistUserEntity(userToBeAdded);
					logger.info("New User added to the database");
					logger.info("OUT UserAddAction");
					return SUCCESS;
				} else {
					logger.error("UITranslations object does not exist for lang code : " + langCode);
					logger.info("OUT AddNewUserAction");
					return ERROR;
				}
			} else {
				logger.info("Role object does not exist in UserAddAction for role ext id: " + userRole);
				return ERROR;
			}
		}
	}

}
